/*            Copyright(c) 2006-2008 Dave Sexton           *
 * http://www.codeplex.com/DocProject                      *
 * http://www.codeplex.com/DocProject/Project/License.aspx *
 ***********************************************************/
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.ObjectModel;
using DaveSexton.DocProject.Resources;

namespace DaveSexton.DocProject.Engine
{
	public class BuildStepCollection : MarshalByRefObject, ICollection<IBuildStep>
	{
		#region Public Properties
		public IBuildEngine Engine
		{
			get
			{
				return engine;
			}
		}

		public IBuildStep this[int index]
		{
			get
			{
				return collection[index];
			}
			set
			{
				if (value == null)
					throw new ArgumentNullException("value");

				if (value.Engine != engine)
					throw new ArgumentException(Errors.BuildStepDifferentEngine, "value");

				collection[index] = value;
			}
		}

		public IBuildStep this[string name]
		{
			get
			{
				foreach (IBuildStep step in collection)
					if (string.Equals(step.Name, name, StringComparison.CurrentCultureIgnoreCase))
						return step;

				return null;
			}
		}
		#endregion

		#region Private / Protected
		private readonly Collection<IBuildStep> collection = new Collection<IBuildStep>();
		private readonly IBuildEngine engine;
		#endregion

		#region Constructors
		/// <summary>
		/// Constructs a new instance of the <see cref="BuildStepCollection" /> class.
		/// </summary>
		public BuildStepCollection(IBuildEngine engine)
		{
			if (engine == null)
				throw new ArgumentNullException("engine");

			this.engine = engine;
		}
		#endregion

		#region Methods
		[System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.LinkDemand,
			Flags = System.Security.Permissions.SecurityPermissionFlag.Infrastructure)]
		public override object InitializeLifetimeService()
		{
			return null;
		}

		public ExternalProcessBuildStep<IBuildEngine> AddExternalProcess(bool continueOnError, string file, params string[] arguments)
		{
			ExternalProcessBuildStep<IBuildEngine> step = new ExternalProcessBuildStep<IBuildEngine>(engine, continueOnError, file, arguments);

			collection.Add(step);

			return step;
		}

		public ExternalProcessBuildStep<IBuildEngine> AddExternalProcess(string file, params string[] arguments)
		{
			ExternalProcessBuildStep<IBuildEngine> step = new ExternalProcessBuildStep<IBuildEngine>(engine, file, arguments);

			collection.Add(step);

			return step;
		}

		public CopyDirectoryBuildStep<IBuildEngine> AddCopyDirectory(string source, string target)
		{
			CopyDirectoryBuildStep<IBuildEngine> step = new CopyDirectoryBuildStep<IBuildEngine>(engine, source, target);

			collection.Add(step);

			return step;
		}

		public CopyDirectoryBuildStep<IBuildEngine> AddCopyDirectory(bool continueOnError, string source, string target)
		{
			CopyDirectoryBuildStep<IBuildEngine> step = new CopyDirectoryBuildStep<IBuildEngine>(engine, continueOnError, source, target);

			collection.Add(step);

			return step;
		}

		public CopyDirectoryBuildStep<IBuildEngine> AddMoveDirectory(string source, string target)
		{
			CopyDirectoryBuildStep<IBuildEngine> step = new CopyDirectoryBuildStep<IBuildEngine>(engine, source, target, true);

			collection.Add(step);

			return step;
		}

		public CopyDirectoryBuildStep<IBuildEngine> AddMoveDirectory(bool continueOnError, string source, string target)
		{
			CopyDirectoryBuildStep<IBuildEngine> step = new CopyDirectoryBuildStep<IBuildEngine>(engine, continueOnError, source, target, true);

			collection.Add(step);

			return step;
		}

		public CopyDirectoryBuildStep<IBuildEngine> AddCopyDirectory(string source, string target, string filePattern)
		{
			CopyDirectoryBuildStep<IBuildEngine> step = new CopyDirectoryBuildStep<IBuildEngine>(engine, source, target, filePattern);

			collection.Add(step);

			return step;
		}

		public CopyDirectoryBuildStep<IBuildEngine> AddCopyDirectory(bool continueOnError, string source, string target, string filePattern)
		{
			CopyDirectoryBuildStep<IBuildEngine> step = new CopyDirectoryBuildStep<IBuildEngine>(engine, continueOnError, source, target, filePattern);

			collection.Add(step);

			return step;
		}

		public CopyDirectoryBuildStep<IBuildEngine> AddMoveDirectory(string source, string target, string filePattern)
		{
			CopyDirectoryBuildStep<IBuildEngine> step = new CopyDirectoryBuildStep<IBuildEngine>(engine, source, target, true, filePattern);

			collection.Add(step);

			return step;
		}

		public CopyDirectoryBuildStep<IBuildEngine> AddMoveDirectory(bool continueOnError, string source, string target, string filePattern)
		{
			CopyDirectoryBuildStep<IBuildEngine> step = new CopyDirectoryBuildStep<IBuildEngine>(engine, continueOnError, source, target, true, filePattern);

			collection.Add(step);

			return step;
		}

		public CopyFileBuildStep<IBuildEngine> AddCopyFile(string source, string target)
		{
			CopyFileBuildStep<IBuildEngine> step = new CopyFileBuildStep<IBuildEngine>(engine, source, target);

			collection.Add(step);

			return step;
		}

		public CopyFileBuildStep<IBuildEngine> AddCopyFile(bool continueOnError, string source, string target)
		{
			CopyFileBuildStep<IBuildEngine> step = new CopyFileBuildStep<IBuildEngine>(engine, continueOnError, source, target);

			collection.Add(step);

			return step;
		}

		public CopyFileBuildStep<IBuildEngine> AddMoveFile(string source, string target)
		{
			CopyFileBuildStep<IBuildEngine> step = new CopyFileBuildStep<IBuildEngine>(engine, source, target, true);

			collection.Add(step);

			return step;
		}

		public CopyFileBuildStep<IBuildEngine> AddMoveFile(bool continueOnError, string source, string target)
		{
			CopyFileBuildStep<IBuildEngine> step = new CopyFileBuildStep<IBuildEngine>(engine, continueOnError, source, target, true);

			collection.Add(step);

			return step;
		}

		public ChangeCurrentDirectoryBuildStep<IBuildEngine> AddChangeCurrentDirectory(string directory)
		{
			ChangeCurrentDirectoryBuildStep<IBuildEngine> step = new ChangeCurrentDirectoryBuildStep<IBuildEngine>(engine, directory);

			collection.Add(step);

			return step;
		}

		public void Insert(int index, IBuildStep item)
		{
			if (item == null)
				throw new ArgumentNullException("item");

			if (item.Engine != engine)
				throw new ArgumentException(Errors.BuildStepDifferentEngine, "item");

			collection.Insert(index, item);
		}

		public int IndexOf(IBuildStep step)
		{
			if (step == null)
				throw new ArgumentNullException("step");

			return collection.IndexOf(step);
		}

		public int IndexOf(string name)
		{
			if (name == null)
				throw new ArgumentNullException("name");

			for (int i = 0; i < collection.Count; i++)
				if (name.Equals(collection[i].Name, StringComparison.CurrentCultureIgnoreCase))
					return i;

			return -1;
		}
		#endregion

		#region ICollection<IBuildStep> Members
		public void Add(IBuildStep item)
		{
			if (item == null)
				throw new ArgumentNullException("item");

			if (item.Engine != engine)
				throw new ArgumentException(Errors.BuildStepDifferentEngine, "item");

			collection.Add(item);
		}

		public void Clear()
		{
			collection.Clear();
		}

		public bool Contains(IBuildStep item)
		{
			return collection.Contains(item);
		}

		public void CopyTo(IBuildStep[] array, int arrayIndex)
		{
			collection.CopyTo(array, arrayIndex);
		}

		public int Count
		{
			get
			{
				return collection.Count;
			}
		}

		public bool IsReadOnly
		{
			get { return false; }
		}

		public bool Remove(IBuildStep item)
		{
			return collection.Remove(item);
		}
		#endregion

		#region IEnumerable<IBuildStep> Members
		public IEnumerator<IBuildStep> GetEnumerator()
		{
			return collection.GetEnumerator();
		}
		#endregion

		#region IEnumerable Members
		System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
		{
			return collection.GetEnumerator();
		}
		#endregion
	}
}
